package common

import (
	"crypto/md5"
	"encoding/hex"
	"encoding/json"
	"errors"
	"strings"
)

// HTTP接口应答
type Response struct {
	Errno int         `json:"errno"`
	Msg   string      `json:"msg"`
	Data  interface{} `json:"data"`
}

type MerInfo struct {
	MerId      string // 商户ID 唯一标识
	MerName    string // 商户名称
	MerSignKey string // 商户密钥 用于验证签名
}

// 下单信息
type OrderToPay struct {
	MerId          string `json:"merId"`          // 商户号
	BusinessNumber string `json:"businessNumber"` // 订单号
	Amount         int    `json:"amount"`         // 订单金额 单位分
	Terminal       string `json:"terminal"`       // 支付类型
	Timestamp      string `josn:"timestamp"`      // 订单时间 时间格式yyyy-MM-dd HH:mm:ss
	ServerUrl      string `json:"serverUrl"`      // 异步通知地址
	GoodsName      string `json:"goodsName"`      // 商品名称
	Sign           string `json:"sign"`           // 签名
}

// 应答方法
func BuildResponse(errno int, msg string, data interface{}) (resp []byte, err error) {

	// 1、定义一个response
	var (
		response Response
	)

	response.Errno = errno
	response.Msg = msg
	response.Data = data

	// 2、序列化json
	resp, err = json.Marshal(response)

	return
}

//  检查商户是否存在（获取商户基本信息) TODO
func CheckMerExisted(merId string) (merInfo *MerInfo, err error) {
	switch merId {
	case "123456":
		merInfo = &MerInfo{
			MerId:      merId,
			MerName:    "小虚的测试商户",
			MerSignKey: "123321",
		}
	default:
		err = errors.New("商户不存在")
		merInfo = &MerInfo{}
	}

	return
}

// 验证签名
func VerifySign(orderInfo OrderToPay, signKey string) (err error) {

	//
	var (
		signStr string
	)

	signStr = "amount=" + string(orderInfo.Amount) + "&businessNumber=" + orderInfo.BusinessNumber + "&goodsName=" + orderInfo.GoodsName + "&merId=" + orderInfo.MerId + "&serverUrl=" + orderInfo.ServerUrl + "&terminal=" + orderInfo.Terminal + "&timestamp" + orderInfo.Timestamp + "&" + signKey

	// md5 + 大写
	signStr = strings.ToUpper(md5V(signStr))

	if orderInfo.Sign != signStr {
		err = errors.New("签名错误")
	}

	return
}

// 生成MD5字符串
func md5V(str string) string {
	h := md5.New()
	h.Write([]byte(str))
	return hex.EncodeToString(h.Sum(nil))
}
